function ChansEnhanced_IsImageBoard(doc)
{
	if (doc.location)
	{
		var href = doc.location.href;
	}
	else if (doc.spec)
	{
		var href = doc.spec;
	}
	for (i in ChansEnhanced_ImageBoards)
	{
		if (ChansEnhanced_ImageBoards[i].string)
		{
			if (href.indexOf(ChansEnhanced_ImageBoards[i].string) != -1)
			{
				return 1;
			}
		}
	}
	return 0;
}
function ChansEnhanced_ToggleSidebar(aURI)
{
	ChansEnhanced_Log("ChansEnhanced_ToggleSidebar("+aURI.spec+")");
	try
	{
		var sidebar = document.getElementById("sidebar");
		if (sidebar)
			var sidebarWindow = sidebar.contentWindow;
		else
			var state = 0;
		if (sidebarWindow && sidebarWindow.location)
		{
			if (sidebarWindow.location.href == 'chrome://chansenhanced/content/sidebar.xul')
				var state = 1;
			else
				var state = 2;
		}
		else
			var state = 0;
	}
	catch(e)
	{
		var state = 0;
	}
	ChansEnhanced_Log("\tSidebar state = "+state);
	if (aURI.spec != 'about:blank' && state != 2)
	{
		if (ChansEnhanced_IsImageBoard(aURI))
		{
			if (!state)
				toggleSidebar('viewChansEnhSidebar',true);
		}
		else if (state)
		{
			toggleSidebar('viewChansEnhSidebar');
		}
	}
}
function ChansEnhanced_CaptchaLoad(event)
{
	ChansEnhanced_Log("ChansEnhanced_CaptchaLoad(event)");
	var doc  = this.ownerDocument;
	var PageID = ChansEnhanced_GetPageID(doc);
	var captLabel = doc.getElementById('CEFormCaptchaLabel');
	captLabel.childNodes[0].nodeValue = "Enter captcha :";
}
function ChansEnhanced_CaptchaFail(event)
{
	ChansEnhanced_Log("ChansEnhanced_CaptchaFail(event)");
	var doc  = this.ownerDocument;
	var PageID = ChansEnhanced_GetPageID(doc);
	ChansEnhanced.Pages[PageID].CaptchaAttempts++;
	var captLabel = doc.getElementById('CEFormCaptchaLabel');
	captLabel.childNodes[0].nodeValue = "Loading captcha ["+ChansEnhanced.Pages[PageID].CaptchaAttempts+"] :";
	var captImg = doc.getElementById('CEFormCaptImg');
	captImg.src = ChansEnhanced_wakaba_GetCaptchaURL(ChansEnhanced.Pages[PageID]);
	ChansEnhanced_Log("\tReloading...");
}
function ChansEnhanced_DoPost(event)
{
	ChansEnhanced_Log("ChansEnhanced_DoPost(event)");
	var doc  = this.ownerDocument;
	var PageID = ChansEnhanced_GetPageID(doc);

	var form = doc.getElementById('CEForm');
	var file = doc.getElementById('CEFormFile');
	var arch = doc.getElementById('CEFormArch');	
	var text = doc.getElementById('CEFormText');
	var subj = doc.getElementById('CEFormSubj');
	var pass = doc.getElementById('CEFormPass');
	var sage = doc.getElementById('CEFormSage');
	var capt = doc.getElementById('CEFormCapt');
	
	if (ChansEnhanced.Pages[PageID].RequestT.captcha && !capt)
	{
		ChansEnhanced_Log("\tCaptcha is needed, trying to load it.");
		capt = doc.createElement("input");
		var captLabel = doc.createElement("label");
		var captImg   = doc.createElement("img");
		
		capt.id	      = 'CEFormCapt';
		capt.type     = 'text';
		
		captImg.id    = 'CEFormCaptImg';
		
		captLabel.title	= "Captcha";
		captLabel.id    = 'CEFormCaptchaLabel';
		captLabel.appendChild(doc.createTextNode("Loading captcha [0] :"));
		captLabel.appendChild(capt);
		captLabel.appendChild(captImg);
		
		form.appendChild(captLabel);
		
		ChansEnhanced.Pages[PageID].CaptchaAttempts = 0;
		captImg.src = ChansEnhanced_wakaba_GetCaptchaURL(ChansEnhanced.Pages[PageID]);
		captImg.addEventListener("load",ChansEnhanced_CaptchaLoad,false);
		captImg.addEventListener("error",ChansEnhanced_CaptchaFail,false);
		captImg.addEventListener("abort",ChansEnhanced_CaptchaFail,false);
	}
	else
	{
		ChansEnhanced_Log("\tSubmitting...");
		ChansEnhanced_Log("\tfile = "+file.value);
		ChansEnhanced_Log("\tarch = "+arch.value);
		ChansEnhanced_Log("\ttext = "+text.value);
		ChansEnhanced_Log("\tsubj = "+subj.value);
		ChansEnhanced_Log("\tpass = "+pass.value);
		ChansEnhanced_Log("\tsage = "+sage.value);
		ChansEnhanced_Log("\tcapt = "+(capt?capt.value:''));
		
		var ReqT	= ChansEnhanced.Pages[PageID].RequestT;
		var ReqF	= ChansEnhanced.Pages[PageID].RequestF;
		var FieldsDone	= {};
		
		var action	= ChansEnhanced.Pages[PageID].Action;
		if (action.indexOf('?') > 0)
			action  = action + '&CEPageID='+PageID;
		else
			action  = action + '?CEPageID='+PageID;
		form.action     = action;
		form.method	= "post";
		ChansEnhanced.Pages[PageID].Request = {
			"text"		: text.value,
			"file"		: file.value,
			"arch"		: arch.value,			
			"subj"		: subj.value,
			"pass"		: pass.value,
			"sage"		: sage.value
		};
		if (ReqT.file)
		{
			if (file.value)
			{
				var nfile = ChansEnhanced_CloneImage(file.value);
				ChansEnhanced_Log("\tnfile = "+nfile);
				file.value = nfile;
				
				if (arch.value)
				{
					ChansEnhanced_Log("\ttry to archive");
					var afile = ChansEnhanced_CreateImgWithArchive(arch.value,file.value);
					if (afile)
					{
						ChansEnhanced_Log("\tafile = "+afile);
						file.value=afile;
						text.value=text.value + ChansEnhanced.ArchiveMark;
					}
					else
					{
						ChansEnhanced_Log("\tarchiving failed");
					}
				}
			}
			file.name  = ReqT.file;
			FieldsDone[ReqT.file]=1;
		}
		if (ReqT.text)
		{
			text.name  = ReqT.text;
			FieldsDone[ReqT.text]=1;
		}
		if (ReqT.password)
		{
			pass.name  = ReqT.password;
			FieldsDone[ReqT.password]=1;
		}
		if (ReqT.subject)
		{
			subj.name  = ReqT.subject;
			FieldsDone[ReqT.subject]=1;
		}
		if (ReqT.email)
		{
			sage.name  = ReqT.email;
			sage.value = sage.checked?'sage':'';
			FieldsDone[ReqT.email]=1;
		}
		if (ReqT.captcha)
		{
			capt.name  = ReqT.captcha;
			FieldsDone[ReqT.captcha]=1;
		}		
		if (ReqT.parent)
		{
			var parentName = [ReqT.parent];
			FieldsDone[ReqT.parent]=1;
		}
		else
		{
			var parentName = ["parent","replythread","threadid","resto"];
		}
		for (var i = 0; i < parentName.length; i++)
		{
			var parent = doc.createElement("input");
			parent.name = parentName[i];
			parent.type = "hidden";
			parent.value= ChansEnhanced.Pages[PageID].ThreadID;
			
			form.appendChild(parent);
		}
		if (ReqT.nofile)
		{
			var nofile = doc.createElement("input");
			if(file.value)
				nofile.value=0;
			else
				nofile.value=1;
			nofile.name = ReqT.nofile;
			
			form.appendChild(nofile);
			FieldsDone[ReqT.nofile]=1;
		}
		if (ReqT.gb2)
		{
			var gb2 = doc.createElement("input");
			gb2.value= 'board';
			gb2.name = ReqT.gb2;
			gb2.type = "hidden";
			form.appendChild(gb2);
			FieldsDone[ReqT.gb2]=1;
		}
		if (ReqT.postredir)
		{
			var postredir = doc.createElement("input");
			postredir.value= 0;
			postredir.name = ReqT.postredir;
			postredir.type = "hidden";
			form.appendChild(postredir);
			FieldsDone[ReqT.postredir]=1;		
		}
		for (i in ReqF)
		{
			if (i != 'length')
			{
				if (!FieldsDone[i])
				{
					var field   = doc.createElement("input");
					field.name  = i;
					field.value = ReqF[i];
					field.type  = "hidden";
					form.appendChild(field);
				}
			}
		}
		form.submit();
	}
}
function ChansEnhanced_Process(doc)
{
	if (ChansEnhanced_wakaba_IsError(doc))
	{
		var pid = doc.location.href.match(/CEPageID=(\d+)/);
		PageID = pid[1];
		var test = ChansEnhanced_evaluateXPath(doc, "/html");
		ChansEnhanced.Pages[PageID].RE = !(test.length);
		var bd   = ChansEnhanced_evaluateXPath(doc, "/html/body",ChansEnhanced.Pages[PageID].RE);
		var PIDHIE = doc.createElement("input");
		PIDHIE.type= "hidden";
		PIDHIE.id  = "CEPageID";
		PIDHIE.value=PageID;
		bd[0].appendChild(PIDHIE);
		return ChansEnhanced_wakaba_ProcessError(doc,ChansEnhanced.Pages[PageID]);
	}
	else
	{
		var PageID = ChansEnhanced_GetUniqueNumber();
		var PIDHIE = doc.createElement("input");
		PIDHIE.type= "hidden";
		PIDHIE.id  = "CEPageID";
		PIDHIE.value=PageID;
		doc.lastChild.childNodes[1].appendChild(PIDHIE);
		
		var test = ChansEnhanced_evaluateXPath(doc, "/html");
		
		ChansEnhanced.Pages[PageID] = {
			"document"	:doc,
			"PageID"	:PageID,
			"RE"		:!(test.length)
		};	
		return ChansEnhanced_wakaba_Process(doc,ChansEnhanced.Pages[PageID]);
	}
}
function ChansEnhanced_ProcessError(doc,page)
{
	var form = doc.getElementById('CEForm');
	var file = doc.getElementById('CEFormFile');
	var arch = doc.getElementById('CEFormArch');
	var text = doc.getElementById('CEFormText');
	var subj = doc.getElementById('CEFormSubj');
	var pass = doc.getElementById('CEFormPass');
	var sage = doc.getElementById('CEFormSage');
	if (page.RequestT.captcha)
	{
		ChansEnhanced_Log("\tCaptcha is needed, trying to load it.");
		var capt = doc.createElement("input");
		var captLabel = doc.createElement("label");
		var captImg   = doc.createElement("img");
		
		capt.id	      = 'CEFormCapt';
		capt.type     = 'text';
		
		captImg.id    = 'CEFormCaptImg';
		
		captLabel.title	= "Captcha";
		captLabel.id    = 'CEFormCaptchaLabel';
		captLabel.appendChild(doc.createTextNode("Loading captcha [0] :"));
		captLabel.appendChild(capt);
		captLabel.appendChild(captImg);
		
		form.appendChild(captLabel);
		
		ChansEnhanced.Pages[page.PageID].CaptchaAttempts = 0;
		captImg.src = ChansEnhanced_wakaba_GetCaptchaURL(page);
		captImg.addEventListener("load",ChansEnhanced_CaptchaLoad,false);
		captImg.addEventListener("error",ChansEnhanced_CaptchaFail,false);
		captImg.addEventListener("abort",ChansEnhanced_CaptchaFail,false);
	}
	file.value = page.Request.file;
	arch.value = page.Request.arch;
	text.value = page.Request.text;
	sage.value = page.Request.sage;
	pass.value = page.Request.pass;
	subj.value = page.Request.subj;
	ChansEnhanced_Log("\tFinished.");
}
function ChansEnhanced_ProcessPostForm(form,inputs,textarea,PageID)
{
	ChansEnhanced.Pages[PageID].RequestF = {};
	ChansEnhanced.Pages[PageID].RequestT = {};
	ChansEnhanced.Pages[PageID].RequestF[textarea.name]	= "";
	ChansEnhanced.Pages[PageID].RequestT.text		= textarea.name;
	ChansEnhanced.Pages[PageID].Action   = form.action;
	for (var i = 0; i < inputs.length; i++)
	{
		var inp = inputs[i];
		if (inp.type == "password" || (inp.oldtype && inp.oldtype == "password" ))
		{
			ChansEnhanced.Pages[PageID].RequestT.password = inp.name;
			ChansEnhanced.Pages[PageID].RequestF[inp.name]	= "";
		}
		else if (inp.type == 'file')
		{
			ChansEnhanced.Pages[PageID].RequestT.file = inp.name;
			ChansEnhanced.Pages[PageID].RequestF[inp.name]	= "";		
		}
		else if (inp.type != 'hidden' && (!inp.style || !inp.style.display || inp.style.display != 'none'))
		{
			if (ChansEnhanced.FieldTypes[inp.name])
			{
				ChansEnhanced.Pages[PageID].RequestT[ChansEnhanced.FieldTypes[inp.name]] = inp.name;
			}
			ChansEnhanced.Pages[PageID].RequestF[inp.name]	= inp.value;
		}
		else if (ChansEnhanced.FieldTypes[inp.name] && ChansEnhanced.FieldTypes[inp.name] == 'parent')
		{
			ChansEnhanced.Pages[PageID].RequestT.parent = inp.name;
			ChansEnhanced.Pages[PageID].RequestF[inp.name]	= 0;
		}
		else
		{
			ChansEnhanced.Pages[PageID].RequestF[inp.name]	= inp.value;
		}
	}
}
function ChansEnhanced_GetPageID(doc)
{
	var PIDHIE = doc.getElementById('CEPageID');
	return PIDHIE.value;
}
function ChansEnhanced_BuildReplyForm(doc)
{
	var form = doc.createElement("form");
	var text = doc.createElement("textarea");
	var subj = doc.createElement("input");
	var pass = doc.createElement("input");
	var sage = doc.createElement("input");
	var file = doc.createElement("input");
	var subm = doc.createElement("input");
	var arch = doc.createElement("input");
	
	var subjLabel = doc.createElement("label");
	var passLabel = doc.createElement("label");
	var sageLabel = doc.createElement("label");
	var fileLabel = doc.createElement("label");
	var archLabel = doc.createElement("label");
	
	form.addEventListener("submit",ChansEnhanced_DoPost,true);
	form.enctype	= 'multipart/form-data';
	form.id		= 'CEForm';
	form.style.display = 'block';
	
	text.id		= 'CEFormText';
	
	subj.id		= 'CEFormSubj';
	subj.type	= 'text';
	
	pass.id		= 'CEFormPass';
	pass.type	= 'password';
	
	sage.id		= 'CEFormSage';
	sage.type	= 'checkbox';
	
	file.id		= 'CEFormFile';
	file.type	= 'file';
	
	arch.id		= 'CEFormArch';
	arch.type	= 'file';	
	
	subm.type	= "button";
	subm.value	= "Post";
	subm.addEventListener("click",ChansEnhanced_DoPost,false);
	
	subjLabel.title	= "Subject";
	subjLabel.appendChild(doc.createTextNode("Subj : "));
	
	passLabel.title	= "Password";
	passLabel.appendChild(doc.createTextNode("Pass : "));

	sageLabel.title	= "Sage";
	sageLabel.appendChild(doc.createTextNode("Sage : "));
	
	fileLabel.title	= "File";
	fileLabel.appendChild(doc.createTextNode("File : "));
	
	archLabel.title	= "Archive";
	archLabel.appendChild(doc.createTextNode("File/Dir to archive (opt): "));
	
	subjLabel.appendChild(subj);
	passLabel.appendChild(pass);
	sageLabel.appendChild(sage);
	fileLabel.appendChild(file);
	archLabel.appendChild(arch);
	
	form.appendChild(text);
	form.appendChild(subjLabel);
	form.appendChild(passLabel);
	form.appendChild(sageLabel);
	form.appendChild(fileLabel);
	form.appendChild(archLabel);	
	form.appendChild(subm);
	
	return form;
}
function ChansEnhanced_CloneImage(img)
{
	if (img)
	{
		var origFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		origFile.initWithPath(img);
		var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
		istream.init(origFile, -1, -1, false);
		var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
		bstream.setInputStream(istream);
		var bytes = bstream.readBytes(bstream.available());	
		
		var fileinfo = ChansEnhanced_GetFileInfo(img);
		var curdate = new Date();
		var timestamp = curdate.getTime();
		
		bytes = bytes + timestamp + ChansEnhanced_GetUniqueNumber();
		
		var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
		file.append(fileinfo.namee+"_"+timestamp+"."+fileinfo.ext);
		file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
		
		var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
		stream.init(file, 0x04 | 0x08 | 0x20, 0600, 0); // write, create, truncate
		stream.write(bytes, bytes.length);
		if (stream instanceof Components.interfaces.nsISafeOutputStream)
		{
			stream.finish();
		}
		else 
		{
			stream.close();
		}
		return file.path;
	}
	else
		return null;
}

function ChansEnhanced_EncryptMsg(cf,text,key)
{
	var time = ChansEnhanced_Time();
	var ef = ChansEnhanced_GetTempFile("msg_"+time+".txt");
	ef = ChansEnhanced_FilePutContents(ef,text);
	
	var sf = ChansEnhanced_GetTempFile("sf_"+time+".jpg");

	var steghide = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
	steghide.initWithPath("C:\\steghide\\steghide.exe");
	var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
	process.init(steghide);
	
	var args = ["embed", "-cf",cf.path,"-ef",ef.path,"-sf",sf.path,"-N","-e","serpent","-z","9","-p",key,"-f"];
	process.run(true, args, args.length);
	return sf;
}
function ChansEnhanced_DecryptMsg(sf,key)
{
	var time = ChansEnhanced_Time();
	var xf = ChansEnhanced_GetTempFile("xf_"+time+".txt");
	
	var steghide = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
	steghide.initWithPath("C:\\steghide\\steghide.exe");
	var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
	process.init(steghide);
	
	var args = ["extract","-sf",sf.path,"-xf",xf.path,"-p",key,"-f"];
	process.run(true, args, args.length);
	
	if (xf.exists())
	{
		var data = ChansEnhanced_FileGetContents(xf);
		return data;
	}
	else
		return null;
}
function ChansEnhanced_CreateImgWithArchive(path,img)
{
	var time = ChansEnhanced_Time();
	var arch = ChansEnhanced_GetTempFile("arch_"+time+".rar");
	
	var archiver = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
	archiver.initWithPath("C:\\Program Files\\WinRAR\\WinRAR.exe");
	var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
	process.init(archiver);
		
	var imgF = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
	imgF.initWithPath(img);
	
	var args = ["a","-o+","-s","-r","-m5","-ep1",arch.path,path];
	process.run(true, args, args.length);
	
	if (arch.exists())
	{
		var FI = ChansEnhanced_GetFileInfo(img);
		var ImgArch = ChansEnhanced_GetTempFile("archI_"+time+"."+FI.ext);
		ChansEnhanced_FilePutContents(ImgArch,ChansEnhanced_FileGetContents(imgF)+ChansEnhanced_FileGetContents(arch));
		return ImgArch.path;
	}
	else
		return null;
}
function ChansEnhanced_GetUniqueNumber()
{
	var i = ChansEnhanced.UniqueNumber;
	ChansEnhanced.UniqueNumber++;
	return i;
}

// ************					FILESYSTEM	************
function ChansEnhanced_GetTemp()
{
	var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
	return file;
}
function ChansEnhanced_GetTempFile(filename)
{
	var file = ChansEnhanced_GetTemp();
	file.append(filename);
	return file;
}
function ChansEnhanced_GetFileInfo(filename)
{
	var pathEnd = 0;
	var extStart= 0;
	if (!((pathEnd = filename.lastIndexOf("\\"))>0))
		pathEnd = filename.lastIndexOf("/");
	extStart = filename.lastIndexOf(".");
	var path = filename.substr(0,pathEnd+1);
	var name = filename.substr(pathEnd+1,filename.length - pathEnd - 1);
	var namee= filename.substr(pathEnd+1,extStart - pathEnd - 1);
	var ext  = filename.substr(extStart+1,filename.length - extStart - 1);
	return {"filename":filename,"path":path,"name":name,"namee":namee,"ext":ext};
}
function ChansEnhanced_FilePutContents(file,data)
{
	var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
	stream.init(file, 0x04 | 0x08 | 0x20, 0600, 0); // write, create, truncate
	stream.write(data, data.length);
	if (stream instanceof Components.interfaces.nsISafeOutputStream)
	{
		stream.finish();
	}
	else 
	{
		stream.close();
	}
	return file;
}
function ChansEnhanced_FileGetContents(file)
{
	var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
	istream.init(file, -1, -1, false);
	var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
	bstream.setInputStream(istream);
	var bytes = bstream.readBytes(bstream.available());
	return bytes;
}
// ************					DATETIME	************
function ChansEnhanced_Time()
{
	var curdate = new Date();
	return curdate.getTime();
}
function ChansEnhanced_GetDate()
{
	var d = new Date();
	return d.getFullYear()+"-"+ChansEnhanced_StrPad(d.getMonth(),2,"0")+"-"+ChansEnhanced_StrPad(d.getDate(),2,"0")+" "+ChansEnhanced_StrPad(d.getHours(),2,"0")+":"+ChansEnhanced_StrPad(d.getMinutes(),2,"0")+":"+ChansEnhanced_StrPad(d.getSeconds(),2,"0");
}
// ************					XPATH   	************
function ChansEnhanced_ReformatXPath(aExpr)
{
	return aExpr.replace(/\/([^\/\[\]\*]+)/gi,"/*[namespace-uri()='http://www.w3.org/1999/xhtml' and name()='\$1']");
}
function ChansEnhanced_evaluateXPath(aNode, aExpr, RE)
{
	if (RE)
		aExpr = ChansEnhanced_ReformatXPath(aExpr);
	var xpe = new XPathEvaluator();
	var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement : aNode.ownerDocument.documentElement);
	var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
	var found = [];
	var res;
	while (res = result.iterateNext())
		found.push(res);
	return found;
}
// ************					String   	************
function ChansEnhanced_StrPad(str,len,pad)
{
	if (str.toString)
		str = str.toString();
	if (str.length < len)
	{
		var diff = len - str.length;
		for (var i = 0; i < diff; i++)
		{
			str = pad + str;
		}
	}
	return str;
}
// ************					DEBUG   	************
function ChansEnhanced_Log(msg)
{
	var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
	file.initWithPath("C:\\ChansEnch\\log.log");
	var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
	foStream.init(file, 0x02 | 0x08 | 0x10, 0666, 0); 
	var data = ChansEnhanced_GetDate()+" "+msg+"\r\n";
	foStream.write(data, data.length);
	foStream.close();
}
function ChansEnhanced_DumpObject(obj)
{
	var maxdepth = 2;
	var res = "";
	if (typeof obj == "object")
	{
		res = "{\r\n";
		for (i in obj)
		{
			try
			{
				var child = obj[i];
			}
			catch(e)
			{
				var child = "<dead>";
			}	
			res += "\t"+i+":"+ChansEnhanced_DumpObjectRecurse(child,1,maxdepth)+",\r\n";
		}
		res += "}\r\n";
		return res;
	}
	else if (typeof obj == "function")
	{
		return "<function>";
	}	
	else
		return obj;
}
function ChansEnhanced_DumpObjectRecurse(obj,depth,maxdepth)
{
	var res = "";
	if (typeof obj == "object")
	{
		if (depth <= maxdepth)
		{
			res = "{\r\n";
			for (i in obj)
			{
				try
				{
					var child = obj[i];
				}
				catch(e)
				{
					var child = "<dead>";
				}
				try
				{
					var childinfo = ChansEnhanced_DumpObjectRecurse(child,depth+1,maxdepth);
				}
				catch(e)
				{
					var childinfo = "<dead>";
				}
				res += ChansEnhanced_StrPad("",depth+1,"\t")+i+":"+childinfo+",\r\n";

			}
			res += ChansEnhanced_StrPad("",depth,"\t")+"}";
		}
		else
			res = "<Object>";
		return res;
	}
	else if (typeof obj == "function")
	{
		return "<function>";
	}
	else
	{
		return obj;
	}
}
ChansEnhanced_Log("internals.js, line 427");